package com.Rsoft.goodWebsocketMan.ui.listener.func;

import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.Rsoft.goodWebsocketMan.Thread.WebSocketServerThread;
import com.Rsoft.goodWebsocketMan.Thread.WebSocketThread;
import com.Rsoft.goodWebsocketMan.domain.WebSocketRq;
import com.Rsoft.goodWebsocketMan.domain.WebSocketServerRq;
import com.Rsoft.goodWebsocketMan.ui.dialog.CommonTipsDialog;
import com.Rsoft.goodWebsocketMan.ui.form.func.WebSocketForm;
import com.Rsoft.goodWebsocketMan.util.StringUtils;
import org.glassfish.tyrus.core.TyrusSession;
import org.springframework.web.socket.WebSocketSession;

import javax.swing.*;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class WebSocketListener {
    private static final Log logger = LogFactory.get();

    public static DefaultListModel<String> listModel = new DefaultListModel<>();

    private WebSocketSession webSocketSession;

    private WebSocketThread currentWebsocketThread;

    private WebSocketServerThread webSocketServerThread;
    /*保存 websocket Session*/
    private static ConcurrentHashMap<String, TyrusSession> sessionHashMap = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<String, String> idNameHashMap = new ConcurrentHashMap<>();

    public static AtomicInteger connectCount = new AtomicInteger(0);

    public static void addSession(String name, TyrusSession session) {
        sessionHashMap.put(name, session);
    }

    public static void delSession(String name) {
        sessionHashMap.remove(name);
    }

    public static ConcurrentHashMap<String, TyrusSession> getSessionHashMap() {
        return sessionHashMap;
    }

    /*添加连接*/
    public static void addConnectList(String name) {
        WebSocketForm webSocketForm = WebSocketForm.getInstance();
        DefaultListModel<String> listModel = (DefaultListModel<String>) webSocketForm.getList1().getModel();
        listModel.addElement(name);
        webSocketForm.getList1().setSelectedIndex(webSocketForm.getList1().getModel().getSize() - 1);
        webSocketForm.getList1().revalidate();
    }

    /*连接按钮*/
    public void addListeners() {
        WebSocketForm webSocketForm = WebSocketForm.getInstance();
        webSocketForm.getToConnectBt().addActionListener(e -> {
            try {
                connect(webSocketForm);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        });
        /*客户端断开连接时间*/
        webSocketForm.getToDisconnectBt().addActionListener(e -> {
            disconnect(webSocketForm);
        });
        /*客户端发送按钮事件*/
        webSocketForm.getSendSend().addActionListener(e -> {
            try {
                sendText();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });
        /*客户端清空接收*/
        webSocketForm.getClearRecv().addActionListener(e -> {
            webSocketForm.getRecvText().setText("");
        });
        /*客户端清空发送*/
        webSocketForm.getClearSend().addActionListener(e -> {
            webSocketForm.getTextAreaSend().setText("");
        });

        /*服务器 */
        webSocketForm.getRunBt().addActionListener(e -> {
            serverRun(webSocketForm);
        });
        /*服务端停止服务*/
        webSocketForm.getKillBt().addActionListener(e -> {
            serverKill(webSocketForm);
        });
        /*服务端清空接收*/
        webSocketForm.getClearRecvBt().addActionListener(e -> {
            clearServerRecvText();
        });
        /*服务端发送清除*/
        webSocketForm.getClearSendBt().addActionListener(e -> {
            clearServerSendext(webSocketForm);
        });
        /*服务端发送按钮*/
        webSocketForm.getServerSendBt().addActionListener(e -> {
            String msg = webSocketForm.getServerSendText().getText();
            String name = webSocketForm.getSendTo().getText();
            if (!StringUtils.isNonNullBlank(name)) {
                CommonTipsDialog dialog = new CommonTipsDialog();
                StringBuilder tipsBuilder = new StringBuilder();
                tipsBuilder.append("请选择要发送给谁？\n");
                tipsBuilder.append("点击连接列表即可选择");
                dialog.setPlaneText(tipsBuilder.toString());
                dialog.pack();
                dialog.setSize(270, 280);
                dialog.setVisible(true);
                return;
            }
            try {
                sessionHashMap.get(name).getBasicRemote().sendText(msg);
                WebSocketForm.getInstance().getServerRecvText().setText(new StringBuilder(WebSocketForm.getInstance().getServerRecvText().getText()).append("[发送给 [[" + name + "]] " + DateUtil.now() + " ]\n" + msg + "\n\n").toString());
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        });
        webSocketForm.getList1().addListSelectionListener(e -> {
            webSocketForm.getSendTo().setText(webSocketForm.getList1().getSelectedValue().toString());
        });
    }

    /*服务端接收消息展示*/
    public static void serverRecvText(String msg) {
        WebSocketForm.getInstance().getServerRecvText().setText(new StringBuilder(WebSocketForm.getInstance().getServerRecvText().getText()).append("[接收于 " + DateUtil.now() + " ]\n" + msg + "\n\n").toString());
    }

    /*清空服务接收信息*/
    private void clearServerRecvText() {
        WebSocketForm.getInstance().getServerRecvText().setText("                              \n");
    }

    private void clearServerSendext(WebSocketForm webSocketForm) {
        webSocketForm.getServerSendText().setText("");
    }

    /*删除连接*/
    public static void delConnectList(String name) {
        WebSocketForm webSocketForm = WebSocketForm.getInstance();
        DefaultListModel<String> listModel = (DefaultListModel<String>) webSocketForm.getList1().getModel();
        listModel.removeElement(name);
        webSocketForm.getList1().revalidate();
    }


    private void serverRun(WebSocketForm webSocketForm) {
        WebSocketServerRq webSocketServerRq = parseServerInfo(webSocketForm);
        if (null == webSocketServerRq) {
            webSocketForm.getStatusTip().setText("启动失败，请检查端口号！");
            return;
        }
        this.webSocketServerThread = new WebSocketServerThread();
        assert webSocketServerRq != null;
        this.webSocketServerThread.setPort(webSocketServerRq.getPort());
        this.webSocketServerThread.start();
        webSocketForm.getStatusTip().setText("服务器启动成功：正在监听：ws://127.0.0.1:" + webSocketServerThread.getPort() + "/ws");
        updateServerBtStatus(webSocketForm);
    }

    private void serverKill(WebSocketForm webSocketForm) {
        this.webSocketServerThread.setFlag(false);
        updateServerBtStatus(webSocketForm);
        DefaultListModel<String> listModel = (DefaultListModel<String>)webSocketForm.getList1().getModel();
        listModel.removeAllElements();
        webSocketForm.getStatusTip().setText("服务器已关闭！");

    }

    private void updateServerBtStatus(WebSocketForm webSocketForm) {
        if (this.webSocketServerThread.isFlag()) {
            webSocketForm.getKillBt().setEnabled(true);
            webSocketForm.getRunBt().setEnabled(false);
        } else {
            webSocketForm.getKillBt().setEnabled(false);
            webSocketForm.getRunBt().setEnabled(true);
        }
    }

    /*解析服务端信息*/
    private WebSocketServerRq parseServerInfo(WebSocketForm webSocketForm) {
        return webSocketForm.getPort().getText().equals("") ? null : new WebSocketServerRq().setPort(Integer.parseInt(webSocketForm.getPort().getText()));
    }

    /*连接*/
    private void connect(WebSocketForm webSocketForm) throws InterruptedException {
        WebSocketRq webSocketRq = parseRqInfo(webSocketForm);
        if (null == webSocketRq)
            webSocketForm.getTips().setText("连接失败，请检查url！");
        this.currentWebsocketThread = new WebSocketThread(webSocketRq);
        this.currentWebsocketThread.start();
        WebSocketForm.getInstance().getTips().setText("连接中....");
        Thread.sleep(1000);
        updateBtStatus(webSocketForm);
    }

    /*断开连接*/
    private void disconnect(WebSocketForm webSocketForm) {
        this.currentWebsocketThread.flag = false;
        updateBtStatus(webSocketForm);
    }

    /*recv*/
    public static void recvText(String msg) {
        WebSocketForm.getInstance().getRecvText().append("[接收于 " + DateUtil.now() + " ]\n" + msg + "\n\n");
    }

    /*send*/
    public void sendText() throws IOException {
        String msg = WebSocketForm.getInstance().getTextAreaSend().getText();
        this.currentWebsocketThread.sendText(msg);
        /*接受框给提示*/
        WebSocketForm.getInstance().getRecvText().append("==>[发送于 " + DateUtil.now() + " ]\n" + "[自己] : " + msg + "\n\n");

    }


    /*server send*/
    public void serverSendText() throws IOException {
        String msg = WebSocketForm.getInstance().getServerSendText().getText();
//        this.webSocketServerThread.sendText(msg);
        /*接受框给提示*/
        WebSocketForm.getInstance().getRecvText().append("==>[发送于 " + DateUtil.now() + " ]\n" + "[自己] : " + msg + "\n\n");

    }

    private void updateBtStatus(WebSocketForm webSocketForm) {
        if (this.currentWebsocketThread.flag) {
            webSocketForm.getToConnectBt().setEnabled(false);
            webSocketForm.getToDisconnectBt().setEnabled(true);
            webSocketForm.getTips().setText("连接成功！");
        } else {
            webSocketForm.getToConnectBt().setEnabled(true);
            webSocketForm.getToDisconnectBt().setEnabled(true);
            webSocketForm.getTips().setText("已断开连接！");
        }
    }

    private WebSocketRq parseRqInfo(WebSocketForm webSocketForm) {
        WebSocketRq webSocketRq = new WebSocketRq();
        String url = webSocketForm.getTextField1().getText();
        String key1 = webSocketForm.getHeader1key().getText();
        String key2 = webSocketForm.getHeader2key().getText();
        String key3 = webSocketForm.getHeader3key().getText();
        String value1 = webSocketForm.getHeader1value().getText();
        String value2 = webSocketForm.getHeader2value().getText();
        String value3 = webSocketForm.getHeader3value().getText();
        if (StringUtils.isNonNullBlank(url))
            webSocketRq.setUrl(url);
        else return null;
        if (StringUtils.isNonNullBlank(key1) && StringUtils.isNonNullBlank(value1)) {
            webSocketRq.getHeaders().put(key1, value1);
        }
        if (StringUtils.isNonNullBlank(key2) && StringUtils.isNonNullBlank(value2)) {
            webSocketRq.getHeaders().put(key2, value2);
        }
        if (StringUtils.isNonNullBlank(key3) && StringUtils.isNonNullBlank(value3)) {
            webSocketRq.getHeaders().put(key3, value3);
        }
        return webSocketRq;
    }
}
